package su.myspringapps.onlineschool.repository;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import su.myspringapps.onlineschool.entity.Course;
import su.myspringapps.onlineschool.entity.Teacher;
import su.myspringapps.onlineschool.entity.enums.CourseType;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class CourseRepositoryTest {

    @Autowired
    CourseRepository courseRepository;

    @Autowired
    TeacherRepository teacherRepository;

    @Test
    void testCreate() throws Exception {
        Course exceptedCourse = new Course();
        exceptedCourse.setName("Cool course");
        exceptedCourse.setDescription("This is the best course in your life !!!");
        exceptedCourse.setDuration(15);
        exceptedCourse.setType(CourseType.MARKETING);
        exceptedCourse.setPrice(500);
        exceptedCourse.setPricePerHour(2.0);
        exceptedCourse.setStudentsCount(25);
        Integer id = courseRepository.create(exceptedCourse);
        exceptedCourse.setId(id);
        Course actualCourse = courseRepository.findById(id);
        Assertions.assertEquals(exceptedCourse, actualCourse);
        courseRepository.delete(actualCourse);
        actualCourse = courseRepository.findById(id);
        Assertions.assertNull(actualCourse);
    }

    @Test
    void testUpdate() throws Exception {
        Course exceptedCourse = new Course();
        exceptedCourse.setName("Cool course");
        exceptedCourse.setDescription("This is the best course in your life !!!");
        exceptedCourse.setDuration(15);
        exceptedCourse.setType(CourseType.MARKETING);
        exceptedCourse.setPrice(500);
        exceptedCourse.setPricePerHour(2.0);
        exceptedCourse.setStudentsCount(25);
        Integer id = courseRepository.create(exceptedCourse);
        exceptedCourse.setId(id);
        Course actualCourse = courseRepository.findById(id);
        Assertions.assertEquals(exceptedCourse, actualCourse);
        exceptedCourse.setStudentsCount(30);
        exceptedCourse.setPrice(654);
        exceptedCourse.setType(CourseType.DESIGN);
        courseRepository.update(exceptedCourse);
        actualCourse = courseRepository.findById(id);
        Assertions.assertEquals(exceptedCourse, actualCourse);
        courseRepository.delete(actualCourse);
        actualCourse = courseRepository.findById(id);
        Assertions.assertNull(actualCourse);
    }

    @Test
    void testDelete() throws Exception {
        Course exceptedCourse = new Course();
        exceptedCourse.setName("Cool course");
        exceptedCourse.setDescription("This is the best course in your life !!!");
        exceptedCourse.setDuration(15);
        exceptedCourse.setType(CourseType.MARKETING);
        exceptedCourse.setPrice(500);
        exceptedCourse.setPricePerHour(2.0);
        exceptedCourse.setStudentsCount(25);
        Integer id = courseRepository.create(exceptedCourse);
        exceptedCourse.setId(id);
        Course actualCourse = courseRepository.findById(id);
        Assertions.assertEquals(exceptedCourse, actualCourse);
        courseRepository.delete(actualCourse);
        actualCourse = courseRepository.findById(id);
        Assertions.assertNull(actualCourse);
    }

    @Test
    void testFindById() throws Exception {
        Course course = courseRepository.findById(1);
        Assertions.assertEquals(
                "Представляем вашему вниманию шикарный курс Веб-разработчик c 0 до PRO",
                course.getDescription());
        Assertions.assertEquals(CourseType.PROGRAMMING, course.getType());
    }

    @Test
    void testFindAll() throws Exception {
        List<Course> courseList = courseRepository.findAll();
        Course actualCourse1 = courseList.get(0);
        Course actualCourse2 = courseList.get(1);
        Course actualCourse3 = courseList.get(2);
        Assertions.assertEquals(
                "Представляем вашему вниманию шикарный курс Мобильный разработчик с нуля",
                actualCourse1.getDescription());
        Assertions.assertEquals(CourseType.PROGRAMMING, actualCourse1.getType());
        Assertions.assertEquals(
                "Представляем вашему вниманию шикарный курс Java-разработчик",
                actualCourse2.getDescription());
        Assertions.assertEquals(CourseType.PROGRAMMING, actualCourse1.getType());
        Assertions.assertEquals(
                "Представляем вашему вниманию шикарный курс PHP-разработчик с 0 до PRO",
                actualCourse3.getDescription());
        Assertions.assertEquals(CourseType.PROGRAMMING, actualCourse1.getType());
    }

    @Test
    void testAssignTeacherToCourse() throws Exception {
        Teacher expectedTeacher = new Teacher();
        expectedTeacher.setName("Шантор Червиз");
        expectedTeacher.setSalary(15550);
        expectedTeacher.setAge(22);
        Integer teacherId = teacherRepository.create(expectedTeacher);
        expectedTeacher.setCourses(new ArrayList<>());
        Course exceptedCourse = new Course();
        exceptedCourse.setName("Cool course");
        exceptedCourse.setDescription("This is the best course in your life !!!");
        exceptedCourse.setDuration(15);
        exceptedCourse.setType(CourseType.MARKETING);
        exceptedCourse.setPrice(500);
        exceptedCourse.setPricePerHour(2.0);
        exceptedCourse.setStudentsCount(25);
        Integer courseId = courseRepository.create(exceptedCourse);
        courseRepository.assignTeacherToCourse(expectedTeacher, exceptedCourse);
        Teacher actualTeacher = teacherRepository.findById(teacherId);
        Course actualCourse = courseRepository.findById(courseId);
        Assertions.assertEquals(exceptedCourse.getDescription(), actualTeacher.getCourses().get(0).getDescription());
        Assertions.assertEquals(exceptedCourse.getType(), actualTeacher.getCourses().get(0).getType());
        Assertions.assertEquals(exceptedCourse.getName(), actualTeacher.getCourses().get(0).getName());
        Assertions.assertEquals(expectedTeacher.getName(), actualCourse.getTeacher().getName());
        Assertions.assertEquals(expectedTeacher.getAge(), actualCourse.getTeacher().getAge());
        Assertions.assertEquals(expectedTeacher.getName(), actualCourse.getTeacher().getName());
        courseRepository.delete(actualCourse);
        teacherRepository.delete(actualTeacher);
        actualTeacher = teacherRepository.findById(teacherId);
        actualCourse = courseRepository.findById(courseId);
        Assertions.assertNull(actualTeacher);
        Assertions.assertNull(actualCourse);
    }

    @Test
    void testUnassignTeacherFromCourse() throws Exception {
        Teacher expectedTeacher = new Teacher();
        expectedTeacher.setName("Шантор Червиз");
        expectedTeacher.setSalary(15550);
        expectedTeacher.setAge(22);
        Integer teacherId = teacherRepository.create(expectedTeacher);
        expectedTeacher.setCourses(new ArrayList<>());
        Course exceptedCourse = new Course();
        exceptedCourse.setName("Cool course");
        exceptedCourse.setDescription("This is the best course in your life !!!");
        exceptedCourse.setDuration(15);
        exceptedCourse.setType(CourseType.MARKETING);
        exceptedCourse.setPrice(500);
        exceptedCourse.setPricePerHour(2.0);
        exceptedCourse.setStudentsCount(25);
        Integer courseId = courseRepository.create(exceptedCourse);
        courseRepository.assignTeacherToCourse(expectedTeacher, exceptedCourse);
        Teacher actualTeacher = teacherRepository.findById(teacherId);
        Course actualCourse = courseRepository.findById(courseId);
        Assertions.assertEquals(exceptedCourse.getDescription(), actualTeacher.getCourses().get(0).getDescription());
        Assertions.assertEquals(exceptedCourse.getType(), actualTeacher.getCourses().get(0).getType());
        Assertions.assertEquals(exceptedCourse.getName(), actualTeacher.getCourses().get(0).getName());
        Assertions.assertEquals(expectedTeacher.getName(), actualCourse.getTeacher().getName());
        Assertions.assertEquals(expectedTeacher.getAge(), actualCourse.getTeacher().getAge());
        Assertions.assertEquals(expectedTeacher.getName(), actualCourse.getTeacher().getName());
        courseRepository.unassignTeacherFromCourse(actualTeacher, actualCourse);
        Assertions.assertNull(actualCourse.getTeacher());
        Assertions.assertEquals(actualTeacher.getCourses().size(), 0);
        courseRepository.delete(actualCourse);
        teacherRepository.delete(actualTeacher);
        actualTeacher = teacherRepository.findById(teacherId);
        actualCourse = courseRepository.findById(courseId);
        Assertions.assertNull(actualTeacher);
        Assertions.assertNull(actualCourse);
    }
}